import 'dart:async';

import 'package:easy_refresh/easy_refresh.dart';
import 'package:get/get.dart';
import 'package:largefriends/config/lf_im_type.dart';
import 'package:largefriends/entity/entities/lf_message_entity.dart';
import 'package:largefriends/entity/entities/lf_user_entity.dart';
import 'package:largefriends/events/delete_conversation_event.dart';
import 'package:largefriends/events/recall_message_event.dart';
import 'package:largefriends/events/user_relation_event.dart';
import 'package:largefriends/service/manager/lf_event_helper.dart';
import 'package:largefriends/net/lf_api_url.dart';
import 'package:largefriends/net/lf_dio_util.dart';
import 'package:largefriends/pages/lf_base_controller.dart';
import 'package:largefriends/pages/lf_chat_detail/lf_chat_detail_logic.dart';
import 'package:largefriends/res/lf_int_ext.dart';
import 'package:largefriends/res/lf_string_ext.dart';
import 'package:largefriends/service/im/lf_im_service.dart';

import '../../service/lf_auth_service.dart';
import '../lf_home/lf_home_logic.dart';

class LfTabMessageLogic extends LfBaseListController<LfUserEntity> {
  LfAuthService authService = Get.find();
  LfIMService imService = Get.find();
  LfHomeLogic homeLogic = Get.find();

  late LfUserEntity self;
  late MessageCallback callback;
  StreamSubscription? streamSubscriptionRecallMessage,
      streamSubscriptionUserAction,
      streamSubscriptionDeleteConversation,
      streamSubscriptionMessageRead;
  @override
  void onInit() {
    self = authService.currentAccount!;
    super.onInit();
  }

  @override
  void onReady() {
    super.onReady();
    _initListener();
  }

  _initListener() {
    ///web socket 回调
    callback = (LfMessageEntity messageEntity) {
      var type = MessageTypeEnum.values.firstWhere(
          (element) => element.value == messageEntity.type,
          orElse: () => MessageTypeEnum.pong);
      switch (type) {
        case MessageTypeEnum.say:
          //更新last message
          updateLastMessage(messageEntity);
          break;
        case MessageTypeEnum.connected:
          break;
        case MessageTypeEnum.recall:
          // updateUnSendMessage(messageEntity,);
          break;
        case MessageTypeEnum.report:

          ///接收对方已读的消息时间
          break;
        case MessageTypeEnum.error:

          ///根据local id 更改消息的发送状态为失败
          break;
        case MessageTypeEnum.checkOnline:
          break;
        default:
          break;
      }
    };
    imService.addMessageCallBack(callback);

    streamSubscriptionUserAction = LfEventHelper()
        .getEvent()
        .on<UserRelationEvent>()
        .listen((UserRelationEvent event) {
      if (event.type == UserRelationType.block) {
        deleteUser(event.uid);
      }
    });

    streamSubscriptionDeleteConversation = LfEventHelper()
        .getEvent()
        .on<DeleteConversationEvent>()
        .listen((DeleteConversationEvent event) {
      deleteUser(event.uid);
    });

    streamSubscriptionRecallMessage = LfEventHelper()
        .getEvent()
        .on<RecallMessageEvent>()
        .listen((RecallMessageEvent event) {
      dataList.firstWhereOrNull(
        (element) {
          if (element.userId == event.uid) {
            element.messageType = IMMessageType.messageTypeRecall.value;
            update();
            return true;
          }
          return false;
        },
      );
    });
  }

  bool _isSelf(String? uid) {
    return self.userId == uid;
  }

  void updateLastMessage(LfMessageEntity responseEntity) async {
    ///查看当前联系人是否已在列表中
    var chatUserItem = LfUserEntity();
    var inTheChatUsersList = false;
    if (_isSelf(responseEntity.fromUid)) {
      //发送方
      chatUserItem = dataList.firstWhere((element) {
        if (element.userId == responseEntity.toUid) {
          inTheChatUsersList = true;
          updateItemContentAndOrder(element, responseEntity);
          return true;
        } else {
          return false;
        }
      }, orElse: () => LfUserEntity());

      if (inTheChatUsersList == false) {
        ///破冰的没有在消息列表中
        await _getNewMessage(responseEntity.toUid!);
      }
    } else {
      var isChatRegistered = GetInstance().isRegistered<LfChatDetailLogic>();

      String? currentUid;
      if (isChatRegistered) {
        LfChatDetailLogic logic = Get.find();
        currentUid = logic.otherUid;
      }
      //接收方
      chatUserItem = dataList.firstWhere((element) {
        if (element.userId == responseEntity.fromUid) {
          inTheChatUsersList = true;
          if (isChatRegistered && element.userId == currentUid) {
            ///不做任何处理
          } else {
            element.newNumber = element.newNumber + 1;
            homeLogic.changeValueBadges(
                type: BadgeChangeType.message,
                value: homeLogic.badgeEntity.value.newMessage + 1);
          }
          updateItemContentAndOrder(element, responseEntity);

          return true;
        } else {
          return false;
        }
      }, orElse: () => LfUserEntity());

      if (inTheChatUsersList) {
        createMessageNotification(responseEntity, chatUserItem);
      } else {
        ///单纯的+1就好了
        homeLogic.changeValueBadges(
            type: BadgeChangeType.message,
            value: homeLogic.badgeEntity.value.newMessage + 1);
        await _getNewMessage(_isSelf(responseEntity.fromUid)
            ? responseEntity.toUid!
            : responseEntity.fromUid!);
        var temp = dataList.firstWhere((element) {
          if (element.userId == responseEntity.fromUid) {
            return true;
          } else {
            return false;
          }
        }, orElse: () => LfUserEntity());
        createMessageNotification(responseEntity, temp);
      }
    }
  }

  void updateItemContentAndOrder(
      LfUserEntity element, LfMessageEntity responseEntity) {
    if (responseEntity.typeId == IMMessageType.themeClear.value) {
      element.backgroundUrl = "";
      element.backgroundAttachId = "";
      _updateItemContentAndOrder(element, responseEntity);
    } else if (responseEntity.typeId == IMMessageType.themeChange.value) {
      LfDio().get<List<LfUserEntity>>(url: apiChattedUsers, params: {
        "page": 1,
        "offset": 1,
        'profId': _isSelf(responseEntity.fromUid)
            ? responseEntity.toUid!
            : responseEntity.fromUid!
      }).then((data) {
        if (data.isNotEmpty) {
          element.backgroundAttachId = data.first.backgroundAttachId;
          element.backgroundUrl = data.first.backgroundUrl;
          _updateItemContentAndOrder(element, responseEntity);
        } else {
          _updateItemContentAndOrder(element, responseEntity);
        }
      }, onError: (error) {
        _updateItemContentAndOrder(element, responseEntity);
      }).onError((error, stackTrace) {
        _updateItemContentAndOrder(element, responseEntity);
      });
    } else {
      _updateItemContentAndOrder(element, responseEntity);
    }
  }

  _updateItemContentAndOrder(
      LfUserEntity element, LfMessageEntity responseEntity) {
    element
      ..lastMessage = responseEntity.content ?? ''
      ..created = responseEntity.time?.toString() ?? '0'
      ..messageType = responseEntity.typeId.toString();
    if (responseEntity.typeId == IMMessageType.match.value.toString()) {
      element.liked = 1;
      element.likedMe = 1;
    }
    dataList.sort((left, right) {
      return (parseInt(right.created)).compareTo(parseInt(left.created));
    });
    //交换位置
    update();
  }

  Future _getNewMessage(String userId) async {
    await LfDio().get<List<LfUserEntity>>(
      url: apiChattedUsers,
      params: {"page": 1, "offset": 1, 'profId': userId},
    ).then((data) {
      if (data.isNotEmpty) {
        bool isExist = false;
        for (var element in dataList) {
          if (element.userId == userId) {
            isExist = true;
            break;
          }
        }
        if (isExist == false) {
          for (var element in data) {
            if (element.userId == userId) {
              dataList.insert(0, element);
              sortMessage();
              update();
            }
          }
        }
      }
      // imService.addChatUser(data);
    });
  }

  void deleteUser(String uid) {
    var entity = dataList.firstWhereOrNull((element) => element.userId == uid);
    if (entity != null) {
      if (entity.newNumber > 0) {
        homeLogic.changeValueBadges(
            type: BadgeChangeType.message,
            value: homeLogic.badgeEntity.value.newMessage - entity.newNumber);
      }
      dataList.remove(entity);
      sortMessage();
      update();
    }
  }

  void clearBadge({required String uid}) {
    var entity = dataList.firstWhereOrNull((element) => element.userId == uid);
    if (entity != null) {
      if (entity.newNumber > 0) {
        homeLogic.changeValueBadges(
            type: BadgeChangeType.message,
            value: homeLogic.badgeEntity.value.newMessage - entity.newNumber);
        entity.newNumber = 0;
      }
      sortMessage();
      update();
    }
  }

  void createMessageNotification(
      LfMessageEntity responseEntity, LfUserEntity chatUserItem) {
    //后台 且为接收方
    if (imService.isBackground && !_isSelf(responseEntity.fromUid)) {
      String? stringTitle = "";
      String? stringBody = "";
      var messageTypeId = IMMessageType.values.firstWhere(
          (element) => element.value.toString() == responseEntity.typeId,
          orElse: () => IMMessageType.messageTypeUnknow);

      switch (messageTypeId) {
        case IMMessageType.image:
          stringTitle = "";
          stringBody = '[Image]';
          break;
        case IMMessageType.text:
          stringTitle = "";
          stringBody = chatUserItem.lastMessage;
          break;
        default:
          break;
      }
      if (stringTitle.isNullOrEmpty && stringBody.isNullOrEmpty) {
        return;
      }

      ///TODO
      // Map<String, dynamic> extra = {};
      // extra.putIfAbsent(
      //     PushConstants.EXTRA_PARAMS_USER_ID, () => chatUserItem.userId);
      // extra.putIfAbsent(
      //     PushConstants.EXTRA_PARAMS_USER_NAME, () => chatUserItem.username);
      // extra.putIfAbsent(
      //     PushConstants.EXTRA_PARAMS_ROOM_ID, () => chatUserItem.roomId);
      // extra.putIfAbsent(
      //     PushConstants.EXTRA_PARAMS_AVATAR_URL, () => chatUserItem.avatar);
      //
      // extra.putIfAbsent(PushConstants.EXTRA_PARAMS_MESSAGE_ID,
      //         () => responseEntity.messageId);
      //
      // Map<String, dynamic> data = {};
      // data.putIfAbsent(
      //     PushConstants.PUSH_PARAMS_TYPE, () => PushEnum.Message.pushType);
      // data.putIfAbsent(
      //     PushConstants.PUSH_PARAMS_TITLE, () => chatUserItem.username);
      // data.putIfAbsent(PushConstants.PUSH_PARAMS_MESSAGE, () => stringBody);
      // data.putIfAbsent(
      //     PushConstants.PUSH_PARAMS_EXTRA, () => json.encode(extra));
      // NotificationUtil.instance.showMasonOfflineNotification(data);
    }
  }

  void sortMessage() {
    dataList.sort((a, b) => parseInt(b.created).compareTo(parseInt(a.created)));
  }

  @override
  Future<IndicatorResult> getCustomParamHttpRequest(
      {bool isRefresh = false}) async {
    var result =
        await httpRequest(httpUrl: apiChattedUsers, refresh: isRefresh);
    return result;
  }

  @override
  bool filterKey({required LfUserEntity value, required LfUserEntity other}) {
    return value.userId == other.userId;
  }

  @override
  getCustomRequestParam({bool isRefresh = false}) {
    requestParam["new"] = 1;
  }

  @override
  void onClose() {
    imService.removeMessageCallBack(callback);
    streamSubscriptionMessageRead?.cancel();
    streamSubscriptionMessageRead = null;
    streamSubscriptionUserAction?.cancel();
    streamSubscriptionUserAction = null;
    streamSubscriptionDeleteConversation?.cancel();
    streamSubscriptionDeleteConversation = null;
    streamSubscriptionRecallMessage?.cancel();
    streamSubscriptionRecallMessage = null;
    super.onClose();
  }
}
